﻿package divinity.fx.particles
{
	
	import flash.display.*;
	import flash.events.Event;
	
	import divinity.events.WorldEvent;
	import divinity.utils.Calculator;
	import divinity.utils.Filters;
	
	public class Particle extends Sprite
	{
		
		
		private var _world:*;
		private var _def:Object;
		private var calc:Calculator=new Calculator();
		private var _img:*;
		//
		private var _alive:Boolean=true;
		private var _vx:Number;
		private var _vy:Number;
		private var _gravity:Number;
		private var _speed:Number;
		private var _life:Number=0;
		private var _lifespan:Number;
		private var _rotfac:Number;
		private var _scalefac:Number;
		private var _alphafac:Number;
		private var _framefac:Number;
		private var _g:Number=0;		
		public function Particle(wrld:*,def:Object)
		{
			
			_world=wrld;	
			_def=def;
			if(def._img!=null)
			{
				_img=new def._img();
				
			}
			else
			{
				_img=defaultPart();
			}
			
			
			if(def._filters!=null)
			{
				
				Filters.addFilters(_img,def._filters);
			}
			_img.cacheAsBitmap=true;
			addChild(_img);
			
			
			
			//
			var angle:Number=def._angle+((Math.random()*def._spread)-def._spread/2);
			var tmp:Object=calc.getVector(angle);
			_vx=tmp.vx;
			_vy=tmp.vy;
			//
			_speed=def._speed[1]-def._speed[0];
			_speed=Number(def._speed[0]+Math.random()*_speed);
			//
			_lifespan=def._lifespan[1]-def._lifespan[0];
			_lifespan=Number(def._lifespan[0]+Math.random()*_lifespan);
			//
			_scalefac=def._scale[1]-def._scale[0];
			_scalefac/=_lifespan;
			scaleX=Number(def._scale[0]);
			scaleY=Number(def._scale[0]);
			//
			_alphafac=def._alpha[1]-def._alpha[0];
			_alphafac/=_lifespan;
			alpha=Number(def._alpha[0]);
			//
			_rotfac=def._rotation[1]-def._rotation[0];
			_rotfac/=_lifespan;
			rotation=def._rotation[0];
			//
			_gravity=def._gravity/1000;
			//
			
			if(_img is MovieClip)
			{
				if(def._playMe)
				{
					_framefac=_img.totalFrames;
					_framefac/=_lifespan;
					
				}
				
				_img.stop();
			}
			addEventListener(Event.ADDED_TO_STAGE,init);
			//addEventListener(Event.EXISTING,_world.registerExist);
			
		}	
		private function init(e:Event)
		{
			
			var xoffset:Number=(Math.random()*_def._box[0])-_def._box[0]/2;
			var yoffset:Number=(Math.random()*_def._box[1])-_def._box[1]/2;
			x-=xoffset;
			y-=yoffset;
			/*
			*/
			if(_def._onCreate!=null)
			{
				_def._onCreate(this);
			}
			_world.addEventListener(WorldEvent.CYCLE,cycle);
			removeEventListener(Event.ADDED_TO_STAGE,init);
			addEventListener(Event.REMOVED_FROM_STAGE,destroy);
		}
		private function cycle(e:WorldEvent)
		{
			
			var elapsed:int=e.elapsed;
			_life+=elapsed;			
			if(_life>_lifespan)
			{
				_alive=false;
				
			}
			if(_alive)
			{
				_g+=_def._mass*_gravity*elapsed;
				var newx:Number=x+(_vx*(_speed/1000)*elapsed);
				var newy:Number=y+(_vy*(_speed/1000)*elapsed)+(_g*elapsed);
				var newscale:Number=scaleX+_scalefac*elapsed;
				var newalpha:Number=alpha+_alphafac*elapsed;
				var newrotation:Number=rotation+_rotfac*elapsed;
				
				//
				//
				if(_def._playMe)
				{
					var frame:int=Math.round(_framefac*_life);
					_img.gotoAndStop(frame);
				}
				//
				
				scaleX=newscale;
				scaleY=newscale;
				alpha=newalpha;
				if(_def._followPath)
				{
					rotation=calc.point2point({x:x,y:y},{x:newx,y:newy}).k;
				}
				else
				{
					rotation=newrotation;
				}
				x=newx;
				y=newy;	
				if(_def._limit!=null)
				{
					if(y>(_def._limit.y+_def._limit.height))
					{
						y=(_def._limit.y+_def._limit.height);
						_g*=0;
						_speed*=_def._bounce;;
					}
					if(y<(_def._limit.y))
					{
						y=_def._limit.y;
						_vy=0;
						_speed*=_def._bounce;;
					}
					if(x>(_def._limit.x+_def._limit.width))
					{
						x=(_def._limit.x+_def._limit.width);
						_vx*=-1;
						_speed*=_def._bounce;;
					}
					if(x<(_def._limit.x))
					{
						x=(_def._limit.x);
						_vx*=-1;
						_speed*=_def._bounce;;
					}
				}
			}
			else
			{
				removeMe();
			}
			if(_def._onAlive!=null)
			{
				_def._onAlive(this);
			}
			
		}
		private function defaultPart()
		{
			var t:MovieClip=new MovieClip();
			var defColor:Number=0xff0000;
			if(_def._color!=null)
			{
				defColor=Number(_def._color);
			}
			t.graphics.beginFill(defColor,1);
			t.graphics.drawCircle(0,0,10);
			t.graphics.endFill();
			
			
			t.cacheAsBitmap=true
			
			return t;	
			
		}
		private function removeMe()
		{
			if(_def._onDead!=null)
			{
				_def._onDead(this);
			}
			_world.removeEventListener(WorldEvent.CYCLE,cycle);
			parent.removeChild(this)
			
		}
		private function destroy(e:Event)
		{			
			//_world.destroyWO=this;	
			removeEventListener(Event.REMOVED_FROM_STAGE,destroy);
			
		}
		
		
		/**
		 * 
		 * GETTERS/SETTERS
		 * 
		 * */
		public function get vx():Number
		{
			return _vx;
		}
		public function set vx(value:Number):void
		{
			_vx = value;
		}
		
		public function get vy():Number
		{
			return _vy;
		}
		
		public function set vy(value:Number):void
		{
			_vy = value;
		}
		
		public function get gravity():Number
		{
			return _gravity;
		}
		
		public function set gravity(value:Number):void
		{
			_gravity = value;
		}
		
		public function get speed():Number
		{
			return _speed;
		}
		
		public function set speed(value:Number):void
		{
			_speed = value;
		}
		
		public function get gforce():Number
		{
			return _g;
		}
		
		public function set gforce(value:Number):void
		{
			_g = value;
		}
		
		public function get img():*
		{
			return _img;
		}
		
		public function set img(value:*):void
		{
			_img = value;
		}
		
		
	}
	
}